package com.young.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.MDC;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @description：
 * @author: yangyahui01
 * @date: 11/28/24 10:33 AM
 */
public class Result implements Serializable {
    private static final boolean DEFAULT_DEBUG_ENABLED = Boolean.parseBoolean(System.getProperty("debug"));
    private boolean success;
    private transient ResultCode resultCode;
    private transient Boolean debugEnabled;
    private String exception;
    private String message;
    private Map<String, Long> pointers;
    private final Map<String, Object> data;
    private String redirectUrl;
    private String token;
    private String form;
    private Object defaultModel;

    public Result() {
        this(false);
    }

    public Result(boolean success) {
        this.success = false;
        this.resultCode = ResultCode.SYSTEM_ERROR;
        this.message = this.resultCode.message;
        this.data = new HashMap(32);
        this.setSuccess(success);

        try {
            this.debugEnabled = Boolean.parseBoolean(MDC.get("debug")) || Boolean.parseBoolean(System.getProperty("DEBUG"));
        } catch (Exception var3) {
        }

    }

    public Result debug() {
        this.debugEnabled = true;
        return this;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("_redirect_url")
    public String getRedirectUrl() {
        return this.redirectUrl;
    }

    public void setRedirectUrl(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }

    public boolean isSuccess() {
        return this.success;
    }

    private boolean isDebugEnabled() {
        return this.debugEnabled == null ? false : this.debugEnabled;
    }

    public void setSuccess(boolean success) {
        this.success = success;
        if (success) {
            this.setResultCode(ResultCode.SUCCESS);
        } else {
            this.setResultCode(ResultCode.UN_KNOWN);
        }

    }

    public void setSuccess(boolean success, String message) {
        this.success = success;
        if (success) {
            this.setResultCode(ResultCode.SUCCESS, message);
        } else {
            this.setResultCode(ResultCode.UN_KNOWN, message);
        }

    }

    public String getCode() {
        return this.resultCode.code;
    }

    @JsonIgnore
    public ResultCode getResultCode() {
        return this.resultCode;
    }

    public void setResultCode(ResultCode resultCode) {
        this.setResultCode(resultCode, (String)null);
    }

    public void setResultCode(ResultCode resultCode, String message) {
        this.resultCode = resultCode;
        this.message = resultCode.message;
        if (message != null) {
            this.message = message;
        }

        if (ResultCode.SUCCESS.equals(resultCode)) {
            this.success = true;
        } else {
            this.success = false;
        }

    }

    public void exception(Throwable throwable) {
        this.exception(throwable, throwable.getMessage());
    }

    public void exception(Throwable throwable, String message) {
        this.exception(ResultCode.SYSTEM_ERROR, throwable, message);
    }

    public void exception(ResultCode rc, Throwable throwable, String message) {
        if (rc == null) {
            rc = ResultCode.SYSTEM_ERROR;
        }

        this.setResultCode(rc);
        this.setMessage(message);
        if (this.isDebugEnabled() || DEFAULT_DEBUG_ENABLED) {
            this.exception = ExceptionUtils.getRootCauseMessage(throwable);
        }

    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("_exception")
    public String getException() {
        return this.exception;
    }

    public String getMessage() {
        if (this.message != null) {
            return this.message;
        } else {
            return this.resultCode != null ? this.resultCode.message : null;
        }
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Result pointer(String mark) {
        if (this.isDebugEnabled() || DEFAULT_DEBUG_ENABLED) {
            long time = System.currentTimeMillis();
            if (this.pointers == null) {
                this.pointers = new TreeMap();
            }

            this.pointers.put(mark, time);
        }

        return this;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("_pointers")
    public Map<String, Long> getPointers() {
        return this.pointers;
    }

    public Result putData(Map<String, Object> map) {
        if (map != null) {
            this.data.putAll(map);
        }

        return this;
    }

    public Result putData(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

    public <T> T get(String key) {
        return (T) this.data.get(key);
    }

    public <T> T get(String key, T defaultValue) {
        if (!this.data.containsKey(key)) {
            return defaultValue;
        } else {
            Object value = this.data.get(key);
            return value == null ? defaultValue : (T) value;
        }
    }

    public Map<String, Object> retain() {
        return new HashMap(this.data);
    }

    public Map<String, Object> getData() {
        return this.data;
    }

    public String render() {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(this);
        } catch (Exception var2) {
            throw new RuntimeException(var2);
        }
    }

    public void token(String token) {
        this.token = token;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("_token")
    public String getToken() {
        return this.token;
    }

    public void form(String form) {
        this.form = form;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("_form")
    public String getForm() {
        return this.form;
    }

    /*@JsonInclude(JsonInclude.Include.NON_NULL)
    public <T> T getDefaultModel() {
        return this.defaultModel;
    }
*/
    public void setDefaultModel(Object defaultModel) {
        this.defaultModel = defaultModel;
    }

    public void clear() {
        this.data.clear();
        this.resultCode = ResultCode.SYSTEM_ERROR;
    }
}
